/*
 * @描述: 
 * @创建者: kilomChou
 * @Date: 2021-05-09 18:16:45
 * @最后编辑: kilomChou
 * @LastEditTime: 2021-05-19 10:26:51
 */

import Snake from "../../snake/Snake";
import SnakeNode, { ISnakeNodeInit } from "../../snake/SnakeNode";
import BaseWorldManager from "./BaseWorldManager";

/** 世界蛇管理器 */
export default class WorldSnakeMgr extends BaseWorldManager {

    /** 蛇映射 <蛇id,蛇> */
    readonly snakeMap = new Map<number, Snake>();
    /** 蛇映射 <蛇名,蛇id>*/
    readonly snakeNameMap = new Map<string, number>();

    /** 当前蛇唯一标识 */
    private _curSnakeId = 1;
    /** 当前蛇节点唯一标识 */
    private _curSnakeNodeId = 1;

    start() {

    }

    update() {
        for (let i = 0; i < 3; i++) {
            this.snakeMap.forEach(s => s.update(i));
        }
    }

    /** 创建蛇 */
    createSnake(name: string, addToWorld = true) {
        let snake = new Snake(this.world, this._curSnakeId++, name);
        addToWorld && this.addSnake(snake);
        return snake;
    }

    /** 添加蛇到世界 */
    addSnake(snake: Snake) {
        if (this.snakeNameMap.has(snake.name)) {
            snake.name += "_" + snake.id;
        }
        this.snakeMap.set(snake.id, snake);
        this.snakeNameMap.set(snake.name, snake.id);
    }

    /** 从世界中移除蛇 */
    removeSnake(snake: Snake) {
        snake.die(this);
        this.snakeMap.delete(snake.id);
        this.snakeNameMap.delete(snake.name);
    }

    /** 创建蛇节点 */
    createSnakeNode(init: ISnakeNodeInit) {
        let node = snakeNodePool.pop() || new SnakeNode(this.world);
        node.id = this._curSnakeNodeId++;
        node.init(init);
        this.addSnakeNode(node);
        return node;
    }

    /** 添加蛇节点到世界区块 */
    addSnakeNode(node: SnakeNode) {
        //加入到区块
        node.chunks = this.world.getChunks(node);
        node.chunks.forEach(chunk => chunk.addSnakeNode(node));
    }

    /** 从世界区块中移除蛇节点 */
    removeSnakeNode(node: SnakeNode) {
        //从区块的中移除
        node.chunks.forEach(chunk => chunk.removeSnakeNode(node));
        //放入对象池
        snakeNodePool.push(node);
    }

    /** 更新蛇节点所覆盖的区块集合 */
    updateSnakeNodeChunks(node: SnakeNode) {
        node.chunks.forEach(chunk => chunk.removeSnakeNode(node));
        this.addSnakeNode(node);
    }

}

/** 蛇节点对象池 */
const snakeNodePool: SnakeNode[] = [];